﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Our.Umbraco.uDbCompare
{
    public class SessionVars
    {
        /// <summary>
        /// The NodeId as defined by the URL
        /// This is the uDbCompare parent node, which will help determine the connection string & url to use
        /// </summary>
        public static int NodeId
        {
            get
            {
                int nodeId = -1;
                string id = System.Web.HttpContext.Current.Request.QueryString["id"];
                if (!string.IsNullOrEmpty(id))
                    Int32.TryParse(id, out nodeId);
                return nodeId;
            }
        }

        /// <summary>
        /// The local umbraco connection string from the web.config file
        /// </summary>
        public static string CurrentConnectionString
        {
            get { return FormatConnectionString(System.Configuration.ConfigurationSettings.AppSettings["umbracoDbDSN"]); }
        }

        /// <summary>
        /// The cached connection string to the remote server that we're using
        /// </summary>
        public static string RemoteConnectionString
        {
            get
            {
                string session = string.Format("dbcompare_remoteConnectionString_{0}", NodeId);
                string conn = System.Web.HttpContext.Current.Session[session] as string;
                return FormatConnectionString(conn);

            }
            set
            {
                string session = string.Format("dbcompare_remoteConnectionString_{0}", NodeId);
                System.Web.HttpContext.Current.Session[session] = value;
            }
        }

        /// <summary>
        /// Give the connection string for local or remote
        /// </summary>
        /// <param name="useRemoteConnectionString"></param>
        /// <returns></returns>
        public static string GetConnectionString(bool useRemoteConnectionString)
        {
            string connectionString = CurrentConnectionString;
            if (useRemoteConnectionString)
                connectionString = RemoteConnectionString;
            return connectionString;
        }

        /// <summary>
        /// Cache the connection string to the Session with the username & password set
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public static void CacheRemoteConnectionString(string connectionString, string username, string password)
        {
            string connectionstring = connectionString;
            if (connectionstring.Contains("{0}") && connectionstring.Contains("{1}") && !string.IsNullOrEmpty(username))
                SessionVars.RemoteConnectionString = string.Format(connectionstring, username, password);
            else if (connectionstring.Contains("{0}") && !string.IsNullOrEmpty(username))
                SessionVars.RemoteConnectionString = string.Format(connectionstring, username);
            else
                SessionVars.RemoteConnectionString = connectionstring;
        }

        /// <summary>
        /// Find the name of the server (based on the connection string)
        /// </summary>
        /// <param name="useRemoteConnection"></param>
        /// <returns></returns>
        public static string GetServerNameAndDb(bool useRemoteConnectionString)
        {
            return GetServerNameAndDb(useRemoteConnectionString, string.Empty);
        }

        /// <summary>
        /// Find the name of the server (based on the connection string)
        /// if not found, the return notFound string
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="notFound"></param>
        /// <returns></returns>
        public static string GetServerNameAndDb(bool useRemoteConnectionString, string notFound)
        {
            string serverName = null;
            string server = null;
            string database = null;
            string connectionString = GetConnectionString(useRemoteConnectionString);
            
            if (!string.IsNullOrEmpty(connectionString))
            {
                string[] keyValuePairs = connectionString.Split(';');
                foreach (string keyValuePair in keyValuePairs)
                {
                    string[] keyValues = keyValuePair.Split('=');
                    if (keyValues[0].Equals("server", StringComparison.InvariantCultureIgnoreCase))
                        server = keyValues[1];
                    if (keyValues[0].Equals("database", StringComparison.InvariantCultureIgnoreCase))
                        database = keyValues[1];
                }

                serverName = string.Format("{0} -> {1}", server, database);
            }

            if (string.IsNullOrEmpty(server) && string.IsNullOrEmpty(database))
                serverName = notFound;
            return serverName;
        }

        private static string FormatConnectionString(string connectionString)
        {
            if (!connectionString.Contains("Provider"))
                connectionString += ";Provider=SQLOLEDB";
            return connectionString;
        }


        public static bool IsValidDbConnection(bool useRemoteConnectionString)
        {
            string connectionString = GetConnectionString(useRemoteConnectionString);

            if (connectionString.Contains("{")
                    || connectionString.IndexOf("server", StringComparison.InvariantCultureIgnoreCase) < 0
                    || connectionString.IndexOf("database", StringComparison.InvariantCultureIgnoreCase) < 0
                )
                return false;

            return true;
        }

    }
}
